#ifndef __BSP_INTERNAL_FLASH_H
#define __BSP_INTERNAL_FLASH_H

#include "apm32f4xx.h"
#include "apm32f4xx_fmc.h"
#include "usb_config.h"

/**
 * if TEST_USB_SPEED = 0,
 * get a usb disk with real Capacity(80k) through flash, can store files.
 * if TEST_USB_SPEED = 1,
 * get a usb disk with false Capacity(800M) through sram,used to test usb speed.
 */
#define TEST_USB_SPEED                 1//!< define 0 disable test speed function, or 1 enable.


/** define use internal flash size */
#define FLASH_BLK_NBR                  10        //!< the number of internal flash sector used
#define FLASH_BLK_SIZ                  (8*1024)  //!< use size for each sector

/** define Storage disk block num and size */
#define STORAGE_BLK_SIZ                MSC_MEDIA_PACKET

#define REAL_STORAGE_BLK_NBR           (FLASH_BLK_SIZ*FLASH_BLK_NBR)/STORAGE_BLK_SIZ

#if (TEST_USB_SPEED)
    #define STORAGE_BLK_NBR            ((REAL_STORAGE_BLK_NBR)*10240)
#else
    #define STORAGE_BLK_NBR            REAL_STORAGE_BLK_NBR
#endif

/** Base address of the Flash sectors */
#define ADDR_FLASH_SECTOR_0     ((uint32_t)0x08000000) //!< Base address of Sector 0, 16 Kbytes
#define ADDR_FLASH_SECTOR_1     ((uint32_t)0x08004000) //!< Base address of Sector 1, 16 Kbytes
#define ADDR_FLASH_SECTOR_2     ((uint32_t)0x08008000) //!< Base address of Sector 2, 16 Kbytes
#define ADDR_FLASH_SECTOR_3     ((uint32_t)0x0800C000) //!< Base address of Sector 3, 16 Kbytes
#define ADDR_FLASH_SECTOR_4     ((uint32_t)0x08010000) //!< Base address of Sector 4, 64 Kbytes
#define ADDR_FLASH_SECTOR_5     ((uint32_t)0x08020000) //!< Base address of Sector 5, 128 Kbytes
#define ADDR_FLASH_SECTOR_6     ((uint32_t)0x08040000) //!< Base address of Sector 6, 128 Kbytes
#define ADDR_FLASH_SECTOR_7     ((uint32_t)0x08060000) //!< Base address of Sector 7, 128 Kbytes
#define ADDR_FLASH_SECTOR_8     ((uint32_t)0x08080000) //!< Base address of Sector 8, 128 Kbytes
#define ADDR_FLASH_SECTOR_9     ((uint32_t)0x080A0000) //!< Base address of Sector 9, 128 Kbytes
#define ADDR_FLASH_SECTOR_10    ((uint32_t)0x080C0000) //!< Base address of Sector 10, 128 Kbytes
#define ADDR_FLASH_SECTOR_11    ((uint32_t)0x080E0000) //!< Base address of Sector 11, 128 Kbytes

/** according physical address to define the Storage Flash block address */
#define FLASH_BLOCK0_START_ADDR     ADDR_FLASH_SECTOR_2
#define FLASH_BLOCK1_START_ADDR     ADDR_FLASH_SECTOR_3
#define FLASH_BLOCK2_START_ADDR     ADDR_FLASH_SECTOR_4
#define FLASH_BLOCK3_START_ADDR     ADDR_FLASH_SECTOR_5
#define FLASH_BLOCK4_START_ADDR     ADDR_FLASH_SECTOR_6
#define FLASH_BLOCK5_START_ADDR     ADDR_FLASH_SECTOR_7
#define FLASH_BLOCK6_START_ADDR     ADDR_FLASH_SECTOR_8
#define FLASH_BLOCK7_START_ADDR     ADDR_FLASH_SECTOR_9
#define FLASH_BLOCK8_START_ADDR     ADDR_FLASH_SECTOR_10
#define FLASH_BLOCK9_START_ADDR     ADDR_FLASH_SECTOR_11

/** define the sector in which a flash block resides */
#define FLASH_BLOCK0_SECTOR         FMC_SECTOR_2
#define FLASH_BLOCK1_SECTOR         FMC_SECTOR_3
#define FLASH_BLOCK2_SECTOR         FMC_SECTOR_4
#define FLASH_BLOCK3_SECTOR         FMC_SECTOR_5
#define FLASH_BLOCK4_SECTOR         FMC_SECTOR_6
#define FLASH_BLOCK5_SECTOR         FMC_SECTOR_7
#define FLASH_BLOCK6_SECTOR         FMC_SECTOR_8
#define FLASH_BLOCK7_SECTOR         FMC_SECTOR_9
#define FLASH_BLOCK8_SECTOR         FMC_SECTOR_10
#define FLASH_BLOCK9_SECTOR         FMC_SECTOR_11

uint8_t Flash_Write(uint32_t *wbuf, uint32_t writeAddr, uint16_t writeLen);
uint8_t Flash_Read(uint32_t *rbuf, uint32_t readAddr, uint16_t readLen);

#endif /* __BSP_INTERNAL_FLASH_H */

